<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      td {
        /* overflow: hidden; */
        position: relative;
      }
      td input {
        /* width: 100%; */
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
        border: none;
        outline: none;
        background: yellow;
      }

      .btns {
        position: absolute;
        z-index: 9999;
        bottom: -25px;
      }
    </style>
  </head>
  <body>
    <table id="table" border="1">
      <thead>
        <tr>
          <th style="width: 100px">name</th>
          <th style="width: 100px">gender</th>
          <th style="width: 100px">age</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>jack</td>
          <td>boy</td>
          <td>20</td>
        </tr>
        <tr>
          <td>lili</td>
          <td>girl</td>
          <td>21</td>
        </tr>
      </tbody>
    </table>
    <script>
      const table = document.getElementById("table");

      // 打开开关
      // 开关机制保证每次只有一个td被编辑
      let flag = true;

      const oldTd = {};
      let input = null;

      table.onclick = function (e) {
        // 关闭开关
        if (flag === false) return;
        flag = false;

        const td = e.target;
        // 1. 保证只有点击 td 单元格的时候才执行业务逻辑
        if (td.tagName !== "TD") return;
        // 2. 保存单元的内容（原始）
        oldTd.content = td.innerHTML;
        oldTd.td = td;
        // 3. 创建input
        input = document.createElement("input");

        // 4. 将td中的内容，设置给input
        input.value = td.innerHTML;
        // 5. 将input放到td中
        td.innerHTML = "";
        td.append(input);

        // 8. 添加确定取消按钮
        const btns = `
        <div class="btns">
          <button data-action="ok">确定</button>
          <button data-action="no">取消</button>
        </div>
        `;
        td.insertAdjacentHTML("beforeend", btns);

        // 6. input获取焦点
        input.focus();
        // 7. 阻止input click冒泡
        input.onclick = (e) => e.stopPropagation();
      };

      const actions = {
        ok() {
          // ①使用新的td内容替换
          oldTd.td.innerHTML = input.value;
          // ②打开开关 保证下次可以点击
          flag = true;
        },
        no() {
          // ①使用旧的td内容替换
          oldTd.td.innerHTML = oldTd.content;
          // ②打开开关 保证下次可以点击
          flag = true;
        },
      };
      document.body.onclick = function (e) {
        const action = e.target.dataset.action;
        if (action === undefined || actions[action] === undefined) return;
        actions[action].call(e.target);
      };
    </script>
  </body>
</html>
